using System;
using System.Resources;
using System.Reflection;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Syncfusion.Windows.Forms.Tools;
using Syncfusion.Windows.Forms.Tools.XPMenus;
using ctsu.Shared;
using ctsu.BaseForms;
using ctsu.Admin.BusLogic;
using ctsu.Data;
using ctsu.Security;
using ctsu.Admin.Forms.CoreLab;


namespace ctsu.Admin.Forms
{
    public partial class FormMain : Form
    {
        private TabbedMDIManager _tmm;
        public event BusinessLogicEvents.BLReturnIDToRequestingFormHandler ReturnIDToRequester;
        private FormDockingManager _dockManager;
        private Hashtable _htConfigs;
        private Hashtable _htFormBaseActive;
        private Hashtable _htFormInfo;
        private Hashtable _htLoadForms;
        private Hashtable _htMessageQ;
        private Hashtable _htCarryNew;
        private bool _initializing;

        public FormDockingManager DockManager
        {
            get { return this._dockManager; }
        }

        public Hashtable CarryNew
        {
            get { return this._htCarryNew; }
        }

        public Hashtable ConfigSettings
        {
            get { return this._htConfigs; }
        }

        #region initialize
        public FormMain()
        {
            InitializeComponent();
            _tmm = new TabbedMDIManager();
            //_tmm.TabControlAdded += new TabbedMDITabControlEventHandler(_tmm_TabControlAdded);
            _tmm.UseIconsInTabs = false;
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            _initializing = true;
            if (LoginForm.ApplicationSecurity.ApplicationUser.LastName == "Rezuke")
                mnuJoe.Visible = true;

            _htLoadForms = new Hashtable();  //key is form #, formInfo is added when InitializeMenusGroups
            GetUserSettings();
            _tmm.AttachToMdiContainer(this);
            
            this.Text += " - Version: " + Application.ProductVersion + " - User: " + LoginForm.ApplicationSecurity.ApplicationUser.Name;

            //TODO* - make this isolated storage
            //create the reports directory - used to store report feedback
            if (!Directory.Exists(CremaConstants.ReportsDirecotry))
                Directory.CreateDirectory(CremaConstants.ReportsDirecotry);

            //docking manager class to wrap the syncfusion docking manger
            _dockManager = new FormDockingManager(this.dokMgr);

            //initialize images
            //adds images to an image list
            InitializeImages();

            //initialize config data
            //this handles load forms also
            InitializeConfigData();

            _htFormBaseActive = new Hashtable();
            _htMessageQ = new Hashtable();
            _htCarryNew = new Hashtable();

            //init menus and groups
            InitializeMenusGroups();
            _initializing = false; 

        }

        private void GetUserSettings()
        {
            StringCollection sc = (StringCollection)Properties.Settings.Default.WindowCoordinates;
            this.Left = int.Parse(sc[0]);
            this.Top = int.Parse(sc[1]);
            this.Width = int.Parse(sc[2]);
            this.Height = int.Parse(sc[3]);

            groupBar1.SelectedItem = Properties.Settings.Default.QuickBarIndex;

            //for forms to load
            sc = (StringCollection)Properties.Settings.Default.LoadForms;
            if (sc != null)
            {
                foreach (string s in sc)
                    _htLoadForms.Add(s, null);
            }                
        }

        internal void LoadForms()
        {
            foreach (DictionaryEntry de in _htLoadForms)
            {
                FormInfoBase fi = de.Value as FormInfoBase;
                if (fi != null)
                    DisplayForm(fi);
            }
        }

        private bool InitializeImages()
        {
            StringBuilder sb = new StringBuilder();
            //ResourceManager rm = new ResourceManager("Caap.Resources", Assembly.GetExecutingAssembly());
            //Image im = (Image)rm.GetObject("a");
            //imgL1.Images.Add(im);

            //settings are in the config
            string imgSet = Properties.Settings.Default.Images.ToString().Trim();            
            string[] imagIndxs = imgSet.Split(':');
            Hashtable ht = new Hashtable();  //used for keying on index

            foreach (string s in imagIndxs)
            {
                string[] imgIndx = s.Split(',');
                ht.Add(Convert.ToInt32(imgIndx[1]), imgIndx[0]);
            }

            int count = 0;
            while (ht.Contains(count))
            {
                try
                {
                    string image = (string)ht[count];
                    Image img = Image.FromFile(@"Images\" + image);
                    imgL1.Images.Add(img, Color.Transparent);
                    imgL2.Images.Add(img, Color.Transparent);
                    ++count;
                }
                catch (Exception ex)
                {
                    //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                    sb.Append("Error loading images.");
                    sb.Append(Environment.NewLine);
                    sb.Append(ex.Message);
                    MessageBox.Show(this, sb.ToString(), "Load Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return false;
                }
            }
            return true;
        }

        private bool InitializeConfigData()
        {
            //this will contain other hash tables 
            _htConfigs = new Hashtable(5);            

            //forms config data
            Hashtable ht = new Hashtable();
            ht.Add("CloseOnCancel", Properties.Settings.Default.CloseOnCancel);
            ht.Add("CloseOnSave", Properties.Settings.Default.CloseOnSave);
            ht.Add("FieldValidate", Properties.Settings.Default.FieldValidate);
            ht.Add("SummaryValidate", Properties.Settings.Default.SummaryValidate);                        
            _htConfigs.Add("UserOptions", ht);

            return true;

        }

        private void InitializeMenusGroups()
        {
            //use this hashtable to store a reference of the formInfo for forms keyed by form.name 
            this._htFormInfo = new Hashtable();

            //gcrc menu
            //settings are in the config
            string mnuSet = Properties.Settings.Default.GcrcMenu.ToString().Trim();
            string grpSet = Properties.Settings.Default.GcrcGroup.ToString().Trim();
            string[] mnuIDs = mnuSet.Split(':');
            string[] grpIDs = grpSet.Split(':');

            //TODO make this dynamic
            SetMenusGroups(mnuIDs, grpIDs, mnuGcrc, grpVwGcrc);

            mnuSet = Properties.Settings.Default.CoreLabMenu.ToString().Trim();
            grpSet = Properties.Settings.Default.CoreLabGroup.ToString().Trim();
            mnuIDs = mnuSet.Split(':');
            grpIDs = grpSet.Split(':');

            SetMenusGroups(mnuIDs, grpIDs, mnuCoreLab, grpVwCoreLab);

            mnuSet = Properties.Settings.Default.AdminSecurityMenu.ToString().Trim();            
            mnuIDs = mnuSet.Split(':');
            SetMenusGroups(mnuIDs, null, mnuAdminSecurity, null);

            mnuSet = Properties.Settings.Default.AdminQAMenu.ToString().Trim();
            mnuIDs = mnuSet.Split(':');
            SetMenusGroups(mnuIDs, null, mnuAdminQA, null);

            mnuSet = Properties.Settings.Default.AdminCommonMenu.ToString().Trim();
            mnuIDs = mnuSet.Split(':');
            SetMenusGroups(mnuIDs, null, mnuAdminCommon, null);
        }

        private void SetMenusGroups(string[] mnuIDs, string[] grpIDs, ParentBarItem mnu, Syncfusion.Windows.Forms.Tools.GroupView grpvu)
        {
            //use a hashtable as a lookup when iterating thru the menu items
            //if its in a group it has to be in a menu but not vice-versa
            Hashtable htGrp = new Hashtable();

            if (grpIDs != null)
            {
                foreach (string s in grpIDs)
                {                    
                    htGrp.Add(Convert.ToInt32(s), s);
                }
            }

            int id;
            FormInfoBase fi = null;
            ctsu.BaseForms.BarItemEx mi = null;
            GroupViewItemEx gi = null;

            foreach (string s in mnuIDs)
            {
                try
                {
                    id = int.Parse(s);
                    fi = GetFormInfo(id);

                    if (!this._htFormInfo.Contains(fi.Name))
                        this._htFormInfo.Add(fi.ClassName, fi);

                    //get grid meta
                    GetGridMetaData(fi, id);

                    //get special lookups
                    GetSpecialLookups(fi, id);

                    //get search form info
                    GetSearchFormInfo(fi, id);

                    //get search result meta info
                    fi.SearchResultInfo = GetSearchResultInfo(id);

                    mi = new ctsu.BaseForms.BarItemEx(fi, fi.Name);
                    mi.ImageList = imgL1;
                    mi.ImageIndex = fi.ImageIndex;
                    fi.BarItm = mi;
                    mi.Click += new EventHandler(mnuGCRC_Click);
                    mfbMngr.Items.Add(mi);
                    mnu.Items.Add(mi);
                    //use large icons for toolbar
                    if(mnu.ID=="GCRC" || mnu.ID=="Core Lab")
                    {                        
                        bar1.Items.Add(mi);
                    }                   
                    
                    //see if there is a group item for this				
                    if (htGrp.Contains(id))
                    {
                        gi = new GroupViewItemEx(fi, fi.Name);
                        fi.GroupViewItm = gi;
                        gi.ImageIndex = fi.ImageIndex;
                        grpvu.GroupViewItems.Add(gi);
                    }
                    if (this._htLoadForms.Contains(s))
                        _htLoadForms[s] = fi;

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        internal Hashtable GetFormsConfigUserOptions()
        {
            return (Hashtable)this._htConfigs["UserOptions"];            
        }

        public FormInfoBase GetFormInfo(int id)
        {
            StringBuilder sb = new StringBuilder();
            FormInfoBase fib = null;
            string sql = "SELECT * FROM Forms " +
                " WHERE FormID = " + id;

            if (id == 50)
                Console.WriteLine("");

            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;

            try
            {
                reader = DataAccess.GetDataReader(sql);
                bool b = reader.Read();

                int ord = 0;
                if (b)
                {
                    ord = reader.GetOrdinal("DeptID");
                    int dept = reader.GetInt32(ord);

                    ord = reader.GetOrdinal("ImageIndex");
                    int image = reader.GetInt32(ord);

                    string desc = "";
                    ord = reader.GetOrdinal("Description");
                    if (!reader.IsDBNull(ord))
                        desc = reader.GetString(ord);

                    ord = reader.GetOrdinal("Name");
                    string name = reader.GetString(ord);

                    string formClassName = "";
                    ord = reader.GetOrdinal("FormClassName");
                    if (!reader.IsDBNull(ord))
                        formClassName = reader.GetString(ord);

                    string controllerClassName = "";
                    ord = reader.GetOrdinal("ControllerClassName");
                    if (!reader.IsDBNull(ord))
                        controllerClassName = reader.GetString(ord);

                    string businessLogicClassName = "";
                    ord = reader.GetOrdinal("BusinessLogicClassName");
                    if (!reader.IsDBNull(ord))
                        businessLogicClassName = reader.GetString(ord);

                    string tableName = "";
                    ord = reader.GetOrdinal("TableName");
                    if (!reader.IsDBNull(ord))
                        tableName = reader.GetString(ord);

                    string lookups = "";
                    ord = reader.GetOrdinal("Lookups");
                    if (!reader.IsDBNull(ord))
                        lookups = reader.GetString(ord);

                    ord = reader.GetOrdinal("UseFormBase");
                    bool useFormBase = reader.GetBoolean(ord);

                    bool hasCarry = false;
                    ord = reader.GetOrdinal("HasCarry");
                    if (!reader.IsDBNull(ord))
                        hasCarry = reader.GetBoolean(ord);

                    string uniqueField = "";
                    ord = reader.GetOrdinal("UniqueField");
                    if (!reader.IsDBNull(ord))
                        uniqueField = reader.GetString(ord);

                    fib = new FormInfoBase(id, dept, image, desc, formClassName, controllerClassName, businessLogicClassName, name, tableName, lookups,
                        useFormBase, uniqueField, hasCarry);
                }
                return fib;
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve FormInfo!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return (FormInfoBase)null;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        public FormInfoBase GetFormInfo(int id, bool isDialog)
        {
            FormInfoBase fi = GetFormInfo(id);
            //get grid meta
            GetGridMetaData(fi, id);

            //get special lookups
            GetSpecialLookups(fi, id);

            //get search form info
            GetSearchFormInfo(fi, id);

            //get search result meta info
            fi.SearchResultInfo = GetSearchResultInfo(id);

            return fi;
        }

        private void GetGridMetaData(FormInfoBase fib, int id)
        {
            StringBuilder sb = new StringBuilder();
            string sql = "SELECT * FROM FormGrids " +
                " WHERE FormID =" + id;

            Hashtable ht = new Hashtable();
            FormGridMeta fgm;
            int ord = 0;
            if (id == 32)
                Console.WriteLine("");

            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;
            try
            {
                reader = DataAccess.GetDataReader(sql);
                while (reader.Read())
                {
                    fgm = new FormGridMeta();
                    ord = reader.GetOrdinal("GridName");
                    fgm.GridName = reader.GetString(ord);

                    ord = reader.GetOrdinal("TableName");
                    fgm.TableName = reader.GetString(ord);

                    ord = reader.GetOrdinal("OrderField");
                    if (!reader.IsDBNull(ord))
                        fgm.OrderField = reader.GetString(ord);

                    ord = reader.GetOrdinal("ForeignField");
                    if (!reader.IsDBNull(ord))
                        fgm.ForeignField = reader.GetString(ord);

                    ord = reader.GetOrdinal("BusinessLogicClassName");
                    if (!reader.IsDBNull(ord))
                        fgm.BusinessLogicClassName = reader.GetString(ord);

                    ord = reader.GetOrdinal("GridColumnMetaTable");
                    fgm.GridColumnMetaTable = reader.GetString(ord);

                    ord = reader.GetOrdinal("IsRequired");
                    fgm.IsRequired = reader.GetBoolean(ord);

                    ht.Add(fgm.GridName, fgm);
                }
                fib.GridMeta = ht;


                //get grid column meta for each grid
                foreach (FormGridMeta fgm2 in ht.Values)
                {
                    GetGridColumnMetaData(fgm2);
                }
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve GridMetaData!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        private void GetGridColumnMetaData(FormGridMeta fgm)
        {
            StringBuilder sb = new StringBuilder();
            string sql = "SELECT * FROM " + fgm.GridColumnMetaTable +
                " ORDER BY ColOrder";

            Hashtable ht = new Hashtable();
            ArrayList al = new ArrayList();
            FormGridColumnMeta fgcm;
            int ord = 0;
            int key = 0;

            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;
            try
            {
                reader = DataAccess.GetDataReader(sql);
                while (reader.Read())
                {
                    fgcm = new FormGridColumnMeta();
                    ord = reader.GetOrdinal("FieldName");
                    fgcm.FieldName = reader.GetString(ord);

                    ord = reader.GetOrdinal("DisplayName");
                    fgcm.DisplayName = reader.GetString(ord);

                    ord = reader.GetOrdinal("DataType");
                    fgcm.DataType = reader.GetString(ord);

                    ord = reader.GetOrdinal("CellType");
                    fgcm.CellType = reader.GetString(ord);

                    ord = reader.GetOrdinal("ColOrder");
                    if (!reader.IsDBNull(ord))
                        fgcm.ColOrder = reader.GetInt32(ord);

                    ord = reader.GetOrdinal("CellWidth");
                    if (!reader.IsDBNull(ord))
                        fgcm.Width = reader.GetInt32(ord);

                    ord = reader.GetOrdinal("IsHidden");
                    if (!reader.IsDBNull(ord))
                        fgcm.IsHidden = reader.GetBoolean(ord);

                    ord = reader.GetOrdinal("ReadOnly");
                    if (!reader.IsDBNull(ord))
                        fgcm.ReadOnly = reader.GetBoolean(ord);

                    ord = reader.GetOrdinal("IsRequired");
                    if (!reader.IsDBNull(ord))
                        fgcm.IsRequired = reader.GetBoolean(ord);

                    ord = reader.GetOrdinal("VerifyName");
                    if (!reader.IsDBNull(ord))
                        fgcm.VerifyName = reader.GetString(ord);

                    ord = reader.GetOrdinal("Range");
                    if (!reader.IsDBNull(ord))
                        fgcm.Range = reader.GetString(ord);

                    ord = reader.GetOrdinal("ValidationType");
                    if (!reader.IsDBNull(ord))
                        fgcm.ValidationType = reader.GetInt32(ord);

                    al.Add(fgcm);
                    ht.Add(fgcm.FieldName, fgcm);
                    key++;
                }
                fgm.GridColumns = ht;
                fgm.GridColumnsOrdered = al;
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve GridColumnMetaData!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        private void GetSpecialLookups(FormInfoBase fib, int id)
        {
            StringBuilder sb = new StringBuilder();
            string sql = "SELECT * FROM FormSpecialLookups " +
                " WHERE FormID =" + id;

            Hashtable ht = new Hashtable();
            SpecialLookup sl;
            int ord = 0;

            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;
            try
            {
                reader = DataAccess.GetDataReader(sql);

                while (reader.Read())
                {
                    sl = new SpecialLookup();
                    ord = reader.GetOrdinal("FieldName");
                    if (!reader.IsDBNull(ord))
                        sl.FieldName = reader.GetString(ord);

                    ord = reader.GetOrdinal("GridName");
                    if (!reader.IsDBNull(ord))
                        sl.GridName = reader.GetString(ord);

                    ord = reader.GetOrdinal("TableName");
                    sl.TableName = reader.GetString(ord);

                    ord = reader.GetOrdinal("WhereClause");
                    if (!reader.IsDBNull(ord))
                        sl.WhereClause = reader.GetString(ord);

                    ord = reader.GetOrdinal("DisplayField");
                    sl.DisplayField = reader.GetString(ord);

                    ord = reader.GetOrdinal("ValueField");
                    sl.ValueField = reader.GetString(ord);

                    ord = reader.GetOrdinal("OrderField");
                    if (!reader.IsDBNull(ord))
                        sl.OrderField = reader.GetString(ord);

                    ord = reader.GetOrdinal("InsertBlank");
                    if (!reader.IsDBNull(ord))
                        sl.InsertBlank = reader.GetBoolean(ord);

                    ht.Add(sl.FieldName, sl);
                }
                fib.SpecialLookups = ht;
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve SpecialLookups!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        private void GetSearchFormInfo(FormInfoBase fib, int id)
        {
            StringBuilder sb = new StringBuilder();
            string sql = "SELECT * FROM FormSearch " +
                " WHERE FormID =" + id;

            Hashtable ht = new Hashtable();
            SearchInfo si;
            int ord = 0;

            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;
            try
            {
                reader = DataAccess.GetDataReader(sql);
                while (reader.Read())
                {
                    si = new SearchInfo();

                    ord = reader.GetOrdinal("ID");
                    si.ID = reader.GetInt32(ord);

                    ord = reader.GetOrdinal("TableName");
                    if (!reader.IsDBNull(ord))
                        si.TableName = reader.GetString(ord);

                    ord = reader.GetOrdinal("Name");
                    if (!reader.IsDBNull(ord))
                        si.Name = reader.GetString(ord);

                    ord = reader.GetOrdinal("SqlCommand");
                    if (!reader.IsDBNull(ord))
                        si.SqlCommand = reader.GetString(ord);

                    ord = reader.GetOrdinal("ControllerClassName");
                    if (!reader.IsDBNull(ord))
                        si.SearchController = reader.GetString(ord);

                    ord = reader.GetOrdinal("SearchClassName");
                    si.SearchClassName = reader.GetString(ord);

                    string fieldCriteriaSet = "";
                    ord = reader.GetOrdinal("FieldCriteriaSet");
                    if (!reader.IsDBNull(ord))
                    {
                        fieldCriteriaSet = reader.GetString(ord);
                        si.SearchFields = ParseColumnSet(fieldCriteriaSet);
                    }

                    string fieldResultSet = "";
                    ord = reader.GetOrdinal("FieldResultSet");
                    if (!reader.IsDBNull(ord))
                    {
                        fieldResultSet = reader.GetString(ord);
                        si.SearchResultCols = ParseColumnSet(fieldResultSet);
                    }

                    //					ord = reader.GetOrdinal("IsUsingFoxpro");
                    //					si.IsUsingFoxpro = reader.GetBoolean(ord);

                    ht.Add(si.TableName, si);
                }
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve SearchFormInfo!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }

            fib.SearchFormInfo = ht;
                        
            //get table schema			
            foreach (SearchInfo si2 in ht.Values)
            {
                //				if(!si2.IsUsingFoxpro)
                //				{
                if (si2.SqlCommand.Length > 0)
                    si2.TableSchema = Utils.GetTableSchema(null, si2.SqlCommand);
                else
                    si2.TableSchema = Utils.GetTableSchema(si2.TableName, null);
                //				}
            }
        }

        private ArrayList ParseColumnSet(string fieldSet)
        {
            ArrayList al = new ArrayList();
            ReportColumn rf = null;
            int pos;

            string[] aSet = fieldSet.Split(',');

            foreach (string s in aSet)
            {
                rf = new ReportColumn();
                pos = s.IndexOf(":");
                rf.FieldName = s.Substring(0, pos);
                if (s.EndsWith(":"))
                    rf.DisplayName = rf.FieldName;
                else
                    rf.DisplayName = s.Substring(pos + 1);
                al.Add(rf);
            }
            return al;
        }

        private Hashtable GetSearchResultInfo(int id)
        {
            StringBuilder sb = new StringBuilder();
            string sql = "SELECT * FROM FormSearchResultMeta " +
                " WHERE FormID =" + id;

            Hashtable ht = new Hashtable();
            SearchResultInfo si;
            int ord = 0;
            if (id == 46)
                id=46;
            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;
            try
            {
                reader = DataAccess.GetDataReader(sql);
                while (reader.Read())
                {
                    si = new SearchResultInfo();

                    ord = reader.GetOrdinal("FormID");
                    si.ID = reader.GetInt32(ord);

                    ord = reader.GetOrdinal("TableName");
                    if (!reader.IsDBNull(ord))
                        si.TableName = reader.GetString(ord);

                    ord = reader.GetOrdinal("SqlCommand");
                    if (!reader.IsDBNull(ord))
                        si.SqlCommand = reader.GetString(ord);

                    ord = reader.GetOrdinal("SearchClassName");
                    si.SearchClassName = reader.GetString(ord);

                    ord = reader.GetOrdinal("ControllerClassName");
                    if (!reader.IsDBNull(ord))
                        si.SearchController = reader.GetString(ord);

                    ord = reader.GetOrdinal("BLClassName");
                    si.BLClassName = reader.GetString(ord);

                    ord = reader.GetOrdinal("ColumnMeta");
                    string columnMeta = reader.GetString(ord);
                    ParseColumnMeta(si, columnMeta);

                    ht.Add(si.TableName, si);
                }
                return ht;
            }
            catch (Exception ex)
            {
                sb.Append("Could not retrieve SearchResultsInfo!");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                //bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                MessageBox.Show(this, sb.ToString(), "Get FormInfo Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return ht;
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed)
                        reader.Close();
                }
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        private void ParseColumnMeta(SearchResultInfo si, string columnMeta)
        {
            Hashtable ht = new Hashtable();
            ArrayList al = new ArrayList();

            string[] ai = columnMeta.Split(',');
            foreach (string s in ai)
            {
                string[] ai2 = s.Split(':');
                ReportColumn rc = new ReportColumn(ai2[0], ai2[1], Convert.ToInt32(ai2[2]));
                al.Add(rc);
                ht.Add(ai2[0], rc);
            }
            si.SearchResultCols = al;
            si.SearchResultColsH = ht;
        }
        #endregion initialize

        #region form closing
        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveUserSettings();
            Properties.Settings.Default.Save();
        }

        private void SaveUserSettings()
        {
            StringCollection sc = new StringCollection();
            sc.Add(this.Left.ToString());
            sc.Add(this.Top.ToString());
            sc.Add(this.Width.ToString());
            sc.Add(this.Height.ToString());
            Properties.Settings.Default.WindowCoordinates = sc;

            Properties.Settings.Default.QuickBarIndex = groupBar1.SelectedItem;

            //remember open windows
            FormBase fb = null;
            sc = new StringCollection();
            foreach (Form f in _tmm.MdiChildren)
            {
                fb = f as FormBase;
                if (fb != null)
                {
                    FormInfoBase fi = fb.Controller.BusinessLogic.FormInfo;                    
                    sc.Add(fi.ID.ToString());                    
                }
            }
            Properties.Settings.Default.LoadForms = sc;
        }
        #endregion form closing

        #region docking
        private void dokMgr_NewDockStateEndLoad(object sender, EventArgs e)
        {
            //sync the docking view menu
            //this is called after the form_load is completed
            SyncViewMenu();
        }

        private void SyncViewMenu()
        {
            Control ctl = null;
            IEnumerator ie = this.dokMgr.Controls;
            while (ie.MoveNext())
            {
                ctl = (Control)ie.Current;
                if (ctl.Name.StartsWith("group"))
                {
                    if (dokMgr.GetDockVisibility(ctl))
                        mnuQuickBar.Checked = true; ;
                    break;
                }
            }
        }

        private void mnuQuickBar_Click(object sender, EventArgs e)
        {
            Console.Write("Checked: " + mnuQuickBar.Checked.ToString());
            if (mnuQuickBar.Checked)
            {
                mnuQuickBar.Checked = false;
                if (dokMgr.GetDockVisibility(groupBar1))
                    dokMgr.SetDockVisibility(groupBar1, false);
            }
            else
            {
                mnuQuickBar.Checked = true;
                if (!dokMgr.GetDockVisibility(groupBar1))
                    dokMgr.SetDockVisibility(groupBar1, true);
            }
        }

        private void dokMgr_DockStateChanged(object sender, Syncfusion.Windows.Forms.Tools.DockStateChangeEventArgs arg)
        {
            Control ctl = null;
            if (arg.Controls.Length > 0)
            {
                ctl = arg.Controls[0];
            }
            Console.WriteLine("dokMgr_DockStateChanged: " + ctl.Name);

        }

        private void dokMgr_DockVisibilityChanged(object sender, Syncfusion.Windows.Forms.Tools.DockVisibilityChangedEventArgs arg)
        {                        
            Console.WriteLine("dokMgr_DockVisibilityChanged: " + arg.Control.Name + ", action: " + arg.Action.ToString());

            if (arg.Control.Name == "groupBar1")
            {
                mnuQuickBar.Checked = dokMgr.GetDockVisibility(groupBar1);
            }
        }
        #endregion docking

        #region display forms
        private void mnuGCRC_Click(object sender, System.EventArgs e)
        {
            ctsu.BaseForms.BarItemEx mi = (ctsu.BaseForms.BarItemEx)sender;
            DisplayFormPre(mi);
        }
        
        private void grpVw_GroupViewItemSelected(object sender, System.EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            GroupView gv = (GroupView)sender;
            GroupViewItemEx gi = (GroupViewItemEx)gv.GroupViewItems[gv.SelectedItem];
            DisplayFormPre(gi);
        }

        public void DisplayFormPre(object obj)
        {
            FormInfoBase fi = null;
            GroupViewItemEx gi = null;
            ctsu.BaseForms.BarItemEx bi = null;

            bi = obj as ctsu.BaseForms.BarItemEx;
            if (bi != null)
                fi = bi.FormInfo;
            else
            {
                gi = obj as GroupViewItemEx;
                if (gi != null)
                    fi = gi.FormInfo;
            }
            if(fi != null)
                DisplayForm(fi);
        }

        public void DisplayForm(FormInfoBase fi)
        {
            Cursor.Current = Cursors.WaitCursor;
            
            string className = fi.ClassName;
            int pos = className.IndexOf(".");
            if (pos > 0)
                className = className.Substring(pos + 1);
            
            //check if form is already displayed
            foreach (Form f in _tmm.MdiChildren)
            {
                if (f.Name == className)
                {
                    ActivateMdiChild(f);
                    return;
                }
            }

            
            if (fi.UseFormBase)
                DisplayFormBase(fi);
            else
                DisplayFormOther(fi);            
        }

        private void DisplayFormBase(FormInfoBase fi)
        {
            StringBuilder sb = new StringBuilder();
            ctsu.Security.Permission permission = FormSecurity.GetFormAccess(fi, LoginForm.ApplicationSecurity.ApplicationUser);
            if (permission == Permission.AccessDenied)
            {
                MessageBox.Show(this, "You do not have access rights for form: " + fi.Name, "Access Denied");
                return;
            }

            //create an instance of the form
            Type formType = Type.GetType("ctsu.Admin.Forms." + fi.ClassName.Trim());
            if (formType == null)
            {
                MessageBox.Show("This function is not defined yet");
                return;
            }

            //show progress                                    
            this.stsLbl1.Text = "Loading: " + fi.Name + " Form";
            this.stsPgb.Visible = true;
            this.stsPgb.Value = 10;
            this.stbMain.Refresh();
            
            //invoke creation of form instance with a null constructor
            ConstructorInfo info = formType.GetConstructor(Type.EmptyTypes);
            FormBase fb = (FormBase)info.Invoke(null);
            this.stsPgb.Value = 20; //show progress

            //get table schema
            DataTable dt = Utils.GetTableSchema(fi.TableName, null);
            this.stsPgb.Value = 30; //show progress

            //create an instance of the business logic
            //and pass the form, formInfo and table schema to the constructor
            Hashtable ht = (Hashtable)this._htConfigs["UserOptions"];

            Type[] argTypes = new Type[6];
            argTypes[0] = Type.GetType("ctsu.Admin.Forms.FormMain, Caap");
            argTypes[1] = Type.GetType("ctsu.BaseForms.FormBase,ctsu.BaseForms");
            argTypes[2] = Type.GetType("ctsu.BaseForms.FormInfoBase,ctsu.BaseForms");
            argTypes[3] = typeof(DataTable);
            argTypes[4] = typeof(ctsu.Security.Permission);
            argTypes[5] = typeof(Hashtable);

            object[] args = new object[6];
            args[0] = this;  //formMain
            args[1] = fb;  //form
            args[2] = fi;  //formInfo
            args[3] = dt;  //table schema
            args[4] = permission; //security permission
            args[5] = ht;

            //invoke creation of bl
            Type busLog = Type.GetType("ctsu.Admin.BusLogic." + fi.BusinessLogicClassName);
            this.stsPgb.Value = 40; //show progress

            info = busLog.GetConstructor(argTypes);
            IBLFormBase iBL = (IBLFormBase)info.Invoke(args);
            this.stsPgb.Value = 50; //show progress

            //create an instance of the controller
            //pass form and bl to the constructor
            argTypes = new Type[2];
            argTypes[0] = Type.GetType("ctsu.BaseForms.FormBase,ctsu.BaseForms");
            argTypes[1] = Type.GetType("ctsu.BaseForms.IBLFormBase,ctsu.BaseForms");

            //TODO - you don't need to pass the form... you can access it thru the iBL
            args = new object[2];
            args[0] = fb;
            args[1] = iBL;

            //invoke creation of controller
            Type frmContrlr = Type.GetType("ctsu.Admin.BusLogic." + fi.ControllerClassName);
            info = frmContrlr.GetConstructor(argTypes);
            IFormBaseController iFC = (IFormBaseController)info.Invoke(args);
            fb.Controller = iFC;
            this.stsPgb.Value = 70; //show progress

            //DONE now passing these in constructor
            //			if(permission != Permission.ReadOnly)
            //				fb.btnNew.Enabled = true;
            //
            //			iBL.FormSecurity = permission;			
            //			
            //			Hashtable ht = (Hashtable)this._htConfigs["UserOptions"];
            //			iBL.ConfigData = (Hashtable)ht["FormsConfig"];

            if (!iBL.Initialize())
            {
                sb.Append("Could not load form!");
                sb.Append(Environment.NewLine);
                sb.Append(Constants.NotifySupport);
                MessageBox.Show(this, sb.ToString(), "Loading Form Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            iBL.RequestIDFromTarget += new ctsu.BaseForms.BusinessLogicEvents.BLRequestIDFromOtherFormHandler(iBL_RequestIDFromTarget);
            this.stsPgb.Value = 80;  //show progress                  

            iBL.FormIcon = Icon.FromHandle(((Bitmap)this.imgL1.Images[fi.ImageIndex]).GetHicon());
            iBL.GridView += new BusinessLogicEvents.BLGridViewEventHandler(this.OnGridView);
            iBL.TableChange += new ctsu.BaseForms.BusinessLogicEvents.BLTableChangeEventHandler(OnTableChange);
            this.stsPgb.Value = 90;
            fb.MinimumSize = new Size(new Point(0, 0));
            fb.MdiParent = this;
            fb.Activated += new EventHandler(fp_Activated);
            fb.Closed += new EventHandler(fp_Closed);
            fb.Show();
            this.stsPgb.Value = 0;
            this.stsPgb.Visible = false;
            this.stsLbl1.Text = "";
        }

        private void iBL_RequestIDFromTarget(object sender, MessageQEventArgs e)
        {
            this._htMessageQ.Add(e.EventArgs.TargetFormClassName, e);
        }

        private void fp_Closed(object sender, EventArgs e)
        {
            FormBase fb = (FormBase)sender;
            if (_htFormBaseActive.ContainsKey(fb.Name))
                this._htFormBaseActive[fb.Name] = false;
        }

        private void fp_Activated(object sender, EventArgs e)
        {
            if (_initializing)
                return;
            FormBase fb = (FormBase)sender;
            bool activated;
            if (_htFormBaseActive.ContainsKey(fb.Name))
            {
                activated = (bool)_htFormBaseActive[fb.Name];
                if (activated)
                    return;
            }
            else
                _htFormBaseActive.Add(fb.Name, true);

            //this initializes combo boxes to -1 and dates to null
            //for EditMode = empty
            BLFormBaseImpl bl = (BLFormBaseImpl)fb.Controller.BusinessLogic;
            bl.InitializeEmptyControls();
        }

        public void OnTableChange(object sender, BLTableChangeEventArgs e)
        {
            int currentRow = 0;
            if (e is BLTableChangeAdvEventArgs)
                currentRow = ((BLTableChangeAdvEventArgs)e).CurrentRow;
            else
                Console.WriteLine("is BLTableChangeEventArgs");

            FormGrid fg = null;
            Control ctl = this.DockManager.GetDockControl(e.TableName);
            if (ctl != null)
            {
                fg = (FormGrid)ctl;
                fg.SetDataSource(currentRow);
            }
        }

        public void OnGridView(object sender, BLGridViewEventArgs e)
        {
            //Check to see it the grid already exists
            if (this.DockManager.DockControlExists(e.Title))
                return;
            e.GridForm.TopLevel = false;
            e.GridForm.Name = e.Title;


            bool isFirstVisible = true;
            bool isFirstOne = true;
            Control ctl = null;
            IEnumerator ie = dokMgr.Controls;
            while (ie.MoveNext())
            {
                ctl = (Control)ie.Current;
                if (ctl.Name.StartsWith("grd"))
                {
                    isFirstOne = false;
                    if (!dokMgr.GetDockVisibility(ctl))
                    {
                        isFirstVisible = false;
                        dokMgr.SetDockVisibility(ctl, true);
                    }
                    break;
                }
            }
            dokMgr.SuspendLayout();
            if (isFirstOne)
                dokMgr.DockControl(e.GridForm, this, DockingStyle.Bottom, 50);
            else
                dokMgr.DockControl(e.GridForm, ctl, DockingStyle.Tabbed, 0);

            if (!isFirstVisible)
                dokMgr.SetDockVisibility(ctl, false);
            dokMgr.ResumeLayout();
            
        }

        private void DisplayFormOther(FormInfoBase fi)
        {
            StringBuilder sb = new StringBuilder();
            
            //create an instance of the form
            Type formType = Type.GetType("ctsu.Admin.Forms." + fi.ClassName.Trim());
            if (formType == null)
            {
                MessageBox.Show("This function is not defined yet");
                return;
            }

            Permission permission = FormSecurity.GetFormAccess(fi, LoginForm.ApplicationSecurity.ApplicationUser);
            if (permission == Permission.AccessDenied)
            {
                MessageBox.Show(this, "You do not have access rights for form: " + fi.Name, "Access Denied");
                return;
            }

            Type[] argTypes = new Type[4];
            argTypes[0] = Type.GetType("ctsu.Admin.Forms.FormMain,Caap");
            argTypes[1] = Type.GetType("ctsu.BaseForms.FormInfoBase,ctsu.BaseForms");
            argTypes[2] = Type.GetType("ctsu.Security.Permission,ctsu.Security");
            argTypes[3] = Type.GetType("System.Collections.Hashtable");

            object[] args = new object[4];
            args[0] = this;
            args[1] = fi;
            args[2] = permission;

            Hashtable ht = (Hashtable)this._htConfigs["UserOptions"];
            args[3] = (Hashtable)ht["FormsConfig"];

            //object frm = Activator.CreateInstance(formType, argTypes,BindingsFlag.Default );
            ConstructorInfo info = formType.GetConstructor(argTypes);
            Form form = (Form)info.Invoke(args);

            form.MdiParent = this;
            form.Show();			
        }
        #endregion display forms

        #region menu click events
        private void mnuImportIRBProtocol_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("This serverce is unavailable until the new Click Commerce system is in place.");
            return;
            
            //User user = LoginForm.ApplicationSecurity.ApplicationUser;
            //bool hasAccess = false;
            //foreach (Role role in user.Roles)
            //{
            //    if (role.Hierarchy == Hierarchy.Administration &&
            //        role.Access == Permission.Administrator)
            //    {
            //        hasAccess = true;
            //        break;
            //    }
            //    if (role.Item == 37 && role.Hierarchy == Hierarchy.Item &&
            //        role.Access == Permission.Administrator)
            //    {
            //        hasAccess = true;
            //        break;
            //    }
            //}
            //if (!hasAccess)
            //{
            //    MessageBox.Show(this, "You do not have access rights for this funciton.", "Access Denied");
            //    return;
            //}

            //FormIRBData irbf = new FormIRBData();
            //irbf.Show();
        }

        private void mnuImportJournal_Click(object sender, System.EventArgs e)
        {

            User user = LoginForm.ApplicationSecurity.ApplicationUser;
            bool hasAccess = false;
            foreach (Role role in user.Roles)
            {
                if (role.Hierarchy == Hierarchy.Administration &&
                    role.Access == Permission.Administrator)
                {
                    hasAccess = true;
                    break;
                }
                if (role.Item == 37 && role.Hierarchy == Hierarchy.Item &&
                    role.Access == Permission.Administrator)
                {
                    hasAccess = true;
                    break;
                }
            }
            if (!hasAccess)
            {
                MessageBox.Show(this, "You do not have access rights for this funciton.", "Access Denied");
                return;
            }

            FormIRBImportJournal irbf = new FormIRBImportJournal();
            irbf.Show();
        }

        private void mnuImportNano_Click(object sender, EventArgs e)
        {
            ImportNano nf = new ImportNano();
            nf.Owner = this;
            nf.Show();
        }

        private void mnuReportingServices_Click(object sender, EventArgs e)
        {
            FormReportingServices frs = new FormReportingServices();
            frs.Show();
        }

        private void mnuFormReport_Click(object sender, System.EventArgs e)
        {

            StringBuilder sb = new StringBuilder();
            BarItem mi = (BarItem)sender;
            string name = mi.Text;
            string sql = "SELECT * FROM FormReports WHERE Name='" + name + "'";
            //SqlConnection conn = LoginForm.GetSqlConnection();
            IDataReader reader = null;

            try
            {
                reader = DataAccess.GetDataReader(sql);
                if (reader.Read())
                {
                    FormReportInfo fri = new FormReportInfo();
                    fri.ID = reader.GetInt32(0);
                    fri.Name = reader.GetString(1);
                    fri.FormClassName = reader.GetString(2);
                    fri.ControllerClassName = reader.GetString(3);
                    fri.BusinessLogicClassName = reader.GetString(4);
                    fri.MethodName = reader.GetString(5);
                    fri.SPName = reader.GetString(6);
                    fri.Title = reader.GetString(7);
                    fri.Landscape = reader.GetBoolean(8);
                    reader.Close();

                    string sql2 = "SELECT * FROM FormReporstColumnMeta WHERE FormReportID=" + fri.ID +
                        " ORDER BY ColOrder";
                    reader = DataAccess.GetDataReader(sql2);
                    ReportColumnInfo rci;
                    ArrayList al = new ArrayList();
                    while (reader.Read())
                    {
                        rci = new ReportColumnInfo();
                        rci.FieldName = reader.GetString(1);
                        rci.FieldType = reader.GetString(2);
                        rci.DisplayName = reader.GetString(3);
                        rci.ColumnWidth = reader.GetInt32(4);
                        al.Add(rci);
                    }
                    fri.ReportColumns = al;

                    //TODO - make this dynamic as well
                    BaseForms.FormReportBase fr = new FormReportBase();
                    IFormReportBaseController ctl = new FormReportBaseControllerImpl();
                    IBLFormReportBase bl = new BLFormReportBaseImpl();
                    ctl.BLReport = bl;
                    fr.Controller = ctl;
                    bl.FormReport = fr;
                    bl.ReportMeta = fri;
                    fr.Show();
                }
                else
                {
                }
            }
            catch (Exception ex)
            {
                ////ExceptionPolicy.HandleException(ex, "Exception Policy");
                sb.Append("Could not execute reader for mnuFormReport_Click.");
                sb.Append(Environment.NewLine);
                sb.Append("Error message: " + ex.Message);
                MessageBox.Show(this, sb.ToString(), "Execute Reader Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            finally
            {
                if (reader != null)
                    reader.Close();
                //if (conn != null)
                //    conn.Dispose();
            }
        }

        private void mnuTestSampleInfo_Click(object sender, EventArgs e)
        {
            FormTestLabelInfo tli = new FormTestLabelInfo();
            tli.Show();
        }

        private void mnuReportProtocolActiveStatus_Click(object sender, System.EventArgs e)
        {
            FormReportProtocolActiveStatus frp = new FormReportProtocolActiveStatus();
            frp.Owner = this;
            frp.Show();

        }
        #endregion menu click events

        private void mnuArpUtils_Click(object sender, EventArgs e)
        {
            FormArpUtils fau = new FormArpUtils();
            fau.Owner = this;
            fau.Show();
        }

        private void mnuSstPatient_Click(object sender, EventArgs e)
        {
            SstQueryPatient sqp = new SstQueryPatient();
            sqp.Owner = this;
            sqp.Show();
        }

        private void barItem1_Click(object sender, EventArgs e)
        {
            TransferFromSstToTestReference tfs = new TransferFromSstToTestReference();
            tfs.Owner = this;
            tfs.Show();
        }

        private void barItem6_Click(object sender, EventArgs e)
        {
            //qa reports
            QaReports qa = new QaReports();
            qa.Owner = this;
            qa.Show();
        }

        private void mnuRoomUsage_Click(object sender, EventArgs e)
        {
            frmRoomReports rr = new frmRoomReports();
            rr.Owner = this;
            rr.Show();
        }

		private void mnuLookups_Click(object sender, EventArgs e)
		{
			FormLookupDlg f = new FormLookupDlg();
			f.ShowDialog(this);
		}

        

        private void mnuImportVisits_Click_1(object sender, EventArgs e)
        {
            FormImport fim = new FormImport();
            fim.Owner = this;
            fim.Show();
        }
                
    }
}

